package com.yan.service.criteria;

import com.yan.service.criteria.query.GroupBy;
import com.yan.service.criteria.query.OrderBy;
import com.yan.service.criteria.query.Where;
import com.yan.service.utils.ClassUtils;
import com.yan.service.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
public class Analyze {

    public static <T> List<Where> where(T obj) {
        List<Where> list = new ArrayList<>();
        if (null == obj) {
            return list;
        }
        List<Class<?>> clazz = ClassUtils.getClassAll(obj);
        List<Field> fields = ClassUtils.getFieldAll(clazz);
        for (Field field : fields) {
            //直接过滤掉static 修饰的属性
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            try {
                field.setAccessible(true);
                Object value = field.get(obj);
                if (null == value) {
                    continue;
                }
                if (value instanceof String && StringUtils.isBlank(String.valueOf(value))) {
                    continue;
                }
                /*if (value instanceof Number && NumberUtils.isEntity((Number) value)) {
                    continue;
                }*/
                //不写注解 默认取 相等
                String sqlColumn = getSqlColumn(field);
                Query query = field.getAnnotation(Query.class);
                if (query == null) {
                    list.add(new Where(sqlColumn, Where.Mark.equal, value));
                } else {
                    list.add(new Where(sqlColumn, query.where(), value));
                }
            } catch (IllegalAccessException e) {
                log.info("类型:【{}】 解析字段:【{}】 失败:【{}】", obj.getClass(), field, e);
            }
        }
        return list;
    }

    public static <T> List<OrderBy> orderBy(T obj) {
        List<OrderBy> list = new ArrayList<>();
        if (null == obj) {
            return list;
        }

        List<Class<?>> clazz = ClassUtils.getClassAll(obj);
        List<Field> fields = ClassUtils.getFieldAll(clazz);
        for (Field field : fields) {
            if (field.isAnnotationPresent(Query.class)) {
                Query query = field.getAnnotation(Query.class);
                if (query.orderBy() == OrderBy.Mark.empty) {
                    continue;
                }
                String sqlColumn = getSqlColumn(field);
                list.add(new OrderBy(sqlColumn, query.orderBy(), query.orderBySort()));
            }
        }
        Collections.sort(list);
        return list;
    }

    public static <T> List<String> groupBy(T obj) {
        List<String> result = new ArrayList<>();
        if (null == obj) {
            return result;
        }
        List<GroupBy> groupByList = new ArrayList<>();
        List<Class<?>> clazz = ClassUtils.getClassAll(obj);
        List<Field> fields = ClassUtils.getFieldAll(clazz);
        for (Field field : fields) {
            if (field.isAnnotationPresent(Query.class)) {
                Query query = field.getAnnotation(Query.class);
                if (!query.groupBy()) {
                    continue;
                }
                String sqlColumn = getSqlColumn(field);
                groupByList.add(new GroupBy(sqlColumn, query.groupBy(), query.groupSort()));
            }
        }
        Collections.sort(groupByList);
        for (GroupBy groupBy : groupByList) {
            result.add(groupBy.getSqlColumn());
        }
        return result;
    }

    public static String getSqlColumn(Field field) {
        Query query = field.getAnnotation(Query.class);
        if (query == null || StringUtils.isBlank(query.sqlColumn())) {
            //将 field.getName() 驼峰命名 转换成 下划线命名
            return StringUtils.toLine(field.getName());
        }
        return query.sqlColumn();
    }

    public static boolean isSelect(Field field) {
        Query query = field.getAnnotation(Query.class);
        if (query == null || query.isSelect()) {
            return true;
        }
        return false;
    }
}
